#ifndef _ALARM_H
#define _ALARM_H

#include "sn_config.h"

enum alarm_func_num {
    ALARM_FUNC_NUM_VOUT_UNDER = 0,
    ALARM_FUNC_NUM_VOUT_OVER=1,
    ALARM_FUNC_NUM_VIN_UNDER=2,
    ALARM_FUNC_NUM_VIN_OVER=3,
    ALARM_FUNC_NUM_IOUT_OVER=4,
    ALARM_FUNC_NUM_TEMP_OVER=5,
    ALARM_FUNC_NUM_COM_ERROR=6,
    ALARM_FUNC_NUM_FAN_ERROR=7,
	ALARM_FUNC_NUM_MAX_ERROR = ALARM_FUNC_NUM_FAN_ERROR+1,

};
#define ALARM_FUCTION_NUM ALARM_FUNC_NUM_MAX_ERROR  //最大7个告警信息，如果告警增加应该修改此宏
#define FLAUT_MAX_NUM  ALARM_FUCTION_NUM     //最大故障计数
#define WARN_MAX_NUM   ALARM_FUCTION_NUM      //最大警告计数
#define ALARM_OBJ_TYPE_IMM      0 
#define ALARM_OBJ_TYPE_DELAY    1 
#define ALARM_OBJ_TYPE_OFF      0xff
enum  alram_type_t{
    ALARM_TYPE_NONE =0,
    ALARM_TYPE_FALUT,
    ALRAM_TYPE_WARNING,
    ALARM_TYPE_ALL,
};
struct alarm_obj_t 
{
    uint8_t flag;//0 无报警，>0 为对应报警编号
    uint8_t type ;//处理类型 0 无等待，1 有延时等待 0xff
    uint8_t err_code ;//0 不处理，1 告警 2 故障 3 即是告警也是故障
    uint32_t delay_cnt_val;//延迟计数设定值
    uint32_t delay_cnt;   // 延迟计数，每次执行-1，为0 时直接执行 
    uint8_t (*check)(void);
};
struct alram_dev_t
{
    uint32_t pre_faluted;//前一次报警编号
    uint32_t fault_num;//当前报警编号
    uint32_t warn_num ;//当前故障编号
    uint8_t fault_flag_buf[FLAUT_MAX_NUM];//故障标志buf
    uint8_t warn_flag_buf[ WARN_MAX_NUM];//警告标志buf
    struct alarm_obj_t obj[ALARM_FUCTION_NUM];
    int     (*obj_init)(struct alram_dev_t *dev,struct alarm_obj_t *obj,uint8_t num);
    uint8_t (*obj_on)(struct alram_dev_t *dev,uint8_t num);
    uint8_t (*obj_delay_on)(struct alram_dev_t *dev,uint8_t num);
    /**
     * @brief 设置延迟时间
     * 
     */
    int (*set_delay)(struct alram_dev_t *dev,uint8_t num,uint16_t delay);
    int (*get_alarm)(struct alram_dev_t *dev,uint8_t num);
    /**
     * @brief 告警处理函数，应该在主循环中调用
     * @param dev 
     * @return uint8_t  0 没有告警 1 有告警
     */
    uint8_t (*loop_func)(struct alram_dev_t *dev);
    /**
     * @brief 获取告警值
     * 
     * @param dev    
     * @param pflault  报警值数组  
     * @return uint8_t  报警值数组长度
     */
    uint8_t (*get_flault)(struct alram_dev_t *dev,uint8_t *pflault);
		int (*clear_flaut_num)(struct alram_dev_t *dev);
    /**
     * @brief 获取警告标志
     * 
     * @param dev 
     * @param [out]  pwarn 警告标志数组  
     * @return uint8_t pwarn 数组长度 
     */
    uint8_t (*get_warn)(struct alram_dev_t *dev,uint8_t *pwarn);
		int (*clear_warn_num)(struct alram_dev_t *dev);
};
int alarm_init(struct alram_dev_t **dev);
#endif // !_ALARM_H
